/**
 * Project:   warnme-app
 * File:      RestClient.java
 * License: 
 *            This file is licensed under GNU General Public License version 3
 *            http://www.gnu.org/licenses/gpl-3.0.txt
 *
 * Copyright: Bartosz Cichecki [ cichecki.bartosz@gmail.com ]
 * Date:      23-12-2012
 */

package dtu.ds.warnme.app.ws.client.restful;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.entity.StringEntity;

import android.content.Context;
import android.location.Location;
import android.util.Log;

import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;

import dtu.ds.warnme.app.model.impl.Event;
import dtu.ds.warnme.app.model.impl.EventType;
import dtu.ds.warnme.app.model.impl.User;
import dtu.ds.warnme.app.ws.client.https.AsyncHttpsClient;
import dtu.ds.warnme.app.ws.client.https.utils.HttpConstants;
import dtu.ds.warnme.app.ws.client.restful.utils.GsonHolder;
import dtu.ds.warnme.app.ws.client.restful.utils.RestConstants;
import dtu.ds.warnme.app.ws.client.restful.utils.RestUtils;

/**
 * @author Bartosz Cichecki
 * 
 */
public class RestClient extends AsyncHttpsClient {

	private static final String TAG = "RestClient";

	protected String wsContextPath;

	public RestClient(String host, int port, String webServiceContextPath) {
		super(host, port);
		wsContextPath = webServiceContextPath;
	}

	public RestClient(String host, int port, String webServiceContextPath, String username, String password, String realm) {
		super(username, password, realm, host, port);
		wsContextPath = webServiceContextPath;
	}

	public void addEvent(Context context, Event newEvent, AsyncHttpResponseHandler handler) {
		String json = GsonHolder.getGson().toJson(newEvent);

		Log.d(TAG, "Adding event: " + json);

		HttpEntity entity;

		try {
			entity = new StringEntity(json, HttpConstants.CHARSET_UTF8);
		} catch (UnsupportedEncodingException e) {
			Log.e(TAG, "This system does not support required encoding.", e);
			throw new IllegalStateException("This system does not support required encoding.", e);
		}

		List<Header> headers = new ArrayList<Header>();
		RestUtils.decorareHeaderWithMD5(headers, json);

		post(context, RestUtils.getAbsoluteAddress(this, RestConstants.RESOURCE_PATH_EVENTS), RestUtils.getHeadersAsArray(headers), entity,
		        HttpConstants.CONTENT_TYPE_APPLICATION_JSON_CHARSET_UTF8, handler);
	}

	public void downVoteEvent(Context context, Event event, AsyncHttpResponseHandler handler) {
		String params = new StringBuilder().append("?").append(RestConstants.PARAM_ACTION).append("=")
		        .append(RestConstants.PARAM_VALUE_DOWNVOTE).toString();

		put(context, RestUtils.getAbsoluteAddress(this, RestConstants.RESOURCE_PATH_EVENTS, event.getId()) + params, null, handler);
	}

	public void getEvents(Context context, Location currentLocation, int radius, EventType[] types, AsyncHttpResponseHandler handler) {
		RequestParams params = new RequestParams();
		params.put(RestConstants.PARAM_LATITUDE, String.valueOf(currentLocation.getLatitude()));
		params.put(RestConstants.PARAM_LONGITUDE, String.valueOf(currentLocation.getLongitude()));
		params.put(RestConstants.PARAM_BEARING, String.valueOf(currentLocation.getBearing()));
		params.put(RestConstants.PARAM_RADIUS, String.valueOf(radius));
		params.put(RestConstants.PARAM_EVENT_TYPES, RestUtils.getCommaSeparatedString(types));

		get(context, RestUtils.getAbsoluteAddress(this, RestConstants.RESOURCE_PATH_EVENTS), params, handler);
	}

	public void getProfile(Context context, AsyncHttpResponseHandler handler) {
		get(context, RestUtils.getAbsoluteAddress(this, RestConstants.RESOURCE_PATH_PROFILES, RestConstants.RESOURCE_PATH_MY), handler);
	}

	public String getWsContextPath() {
		return wsContextPath;
	}

	public void registerUser(Context context, User user, AsyncHttpResponseHandler handler) {
		String json = GsonHolder.getGson().toJson(user);
		HttpEntity entity;

		Log.d(TAG, "Registering user: " + json);

		try {
			entity = new StringEntity(json, HttpConstants.CHARSET_UTF8);
		} catch (UnsupportedEncodingException e) {
			Log.e(TAG, "This system does not support required encoding.", e);
			throw new IllegalStateException("This system does not support required encoding.", e);
		}

		List<Header> headers = new ArrayList<Header>();
		RestUtils.decorareHeaderWithMD5(headers, json);

		post(context, RestUtils.getAbsoluteAddress(this, RestConstants.RESOURCE_PATH_REGISTER), RestUtils.getHeadersAsArray(headers),
		        entity, HttpConstants.CONTENT_TYPE_APPLICATION_JSON_CHARSET_UTF8, handler);
	}

	public void setWsContextPath(String webServiceContextPath) {
		wsContextPath = webServiceContextPath;
	}

	public void upVoteEvent(Context context, Event event, AsyncHttpResponseHandler handler) {
		String params = new StringBuilder().append("?").append(RestConstants.PARAM_ACTION).append("=")
		        .append(RestConstants.PARAM_VALUE_UPVOTE).toString();

		put(context, RestUtils.getAbsoluteAddress(this, RestConstants.RESOURCE_PATH_EVENTS, event.getId()) + params, null, handler);

	}

}
